﻿unit SysUserService;

interface
{$I ../Config.inc}
uses
  FastMM4,
  FastMove,
  System.SysUtils,
  System.Classes,
  System.Types,
  Winapi.Windows,
  Data.DB,
  Data.Win.ADODB,
  Datasnap.DBClient,
  Datasnap.Provider,
  {$IFDEF UNICODE}
  AnsiStrings,
  {$ENDIF }
  QBParcel,
  DllSpread,
  Generics.Collections,
  DateUtils,
  QJson,
  UserConnection,
  DBAccessor,
  DllPlugin,
  StrUtils,
  SKSOFTComm,
  SysUserModel,
  SysUserBLL,
  SysDeptUserModel,
  SysDepartmentModel,
  SysDeptUserService,
  SysRoleUserModel;
  
type

  TSysUserService = class(TSysUserBLL)
  private

  protected

  public
  {$IFDEF SERVER}
    function BeforeTreatment(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function BeforeTreatment(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;

    function BeforeCheck(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function BeforeCheck(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;

    function Check(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function Check(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;

    function BeforeExecute(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function BeforeExecute(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;

    function AfterTreatment(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
    function AfterTreatment(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;overload;override;
  {$ENDIF}
    function LoadAll(const iItems:TSysUserList; out oError:string; const iJustUse:Boolean=False):Boolean;
    function LoadById(const iUserId:string; const iItem:TSysUser; out oError:string):Boolean;
    function Login(const iOrgId,iUserId,iPassword:string; out oErrorType:Integer; out oError:string):Boolean;
    function Use(const iItem:TSysUser; out oError:string):Boolean;
  end;
  
implementation

{$IFDEF SERVER}
function TSysUserService.BeforeTreatment(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
var
  ItemDB:TSysUser;
begin
  if iItem<>nil then
  begin
    ItemDB:=TSysUser.Create;
    try
      case iPreMode of
      pmAdd:
        begin
          iItem.UserIsSystem:=False;
          iItem.UserIsUseIm:=False;
          iItem.UserStatus:=1;
          iItem.RecordDate:=Now;
          iItem.ModifyPsn:=EmptyStr;
        end;
      pmEdit:
        begin
          if not iParcel.GoodsExists(AnsiString(iItem.ClassName)) then
          begin
            if ItemDB.LoadFromStr(iItem.SaveToStr,oError) and
              Reload(ItemDB,oError) then
            begin
              iParcel.PutStringGoods(AnsiString(iItem.ClassName),ItemDB.SaveToStr);
            end else begin
              oError:=Format(string('调用%s.BeforeTreatment错误 --> %s'),[Self.ClassName,oError]);
              Result:=False;
              Exit;
            end;
          end else if not ItemDB.LoadFromStr(iParcel.GetStringGoods(AnsiString(iItem.ClassName)),oError) then
          begin
            oError:=Format(string('调用%s.BeforeTreatment错误 --> %s'),[Self.ClassName,oError]);
            Result:=False;
            Exit;
          end;

          iItem.ModifyDate:=Now;
        end;
      pmDelete:
        begin
          if not Reload(iItem,oError) then
          begin
            oError:=Format(string('调用%s.BeforeTreatment错误 --> %s'),[Self.ClassName,oError]);
            Result:=False;
            Exit;
          end;
        end;
      end;
    finally
      FreeAndNil(ItemDB);
    end;
  end else begin
    oError:=Format(string('调用%s.BeforeTreatment错误...错误内容:传入的对象或字符串为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysUserService.BeforeTreatment(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysUserService.BeforeCheck(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysUserService.BeforeCheck(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysUserService.Check(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
var
  ItemDB:TSysUser;
  SQL,SQLResultStr:string;
begin
  if iItem<>nil then
  begin
    ItemDB:=TSysUser.Create;
    try
      if SameStr(Trim(iItem.UserId),EmptyStr) then
      begin
        oError:='用户账号不允许为空';
        Result:=False;
        Exit;
      end else if SameStr(Trim(iItem.UserName),EmptyStr) then
      begin
        oError:='用户姓名不允许为空';
        Result:=False;
        Exit;
      end else if SameStr(Trim(iItem.UserPassword),EmptyStr) then
      begin
        oError:='用户密码不允许为空';
        Result:=False;
        Exit;
      end else if iItem.UserIsSystem then
      begin
        oError:='不允许创建、修改、删除系统内置用户';
        Result:=False;
        Exit;
      end else if (iItem.UserStatus<0) or (iItem.UserStatus>1) then
      begin
        oError:='用户状态非法';
        Result:=False;
        Exit;
      end;

      case iPreMode of
      pmAdd:
        begin
          if SameStr(Trim(iItem.RecordPsn),EmptyStr) then
          begin
            oError:='录入人不允许为空';
            Result:=False;
            Exit;
          end;
        end;
      pmEdit:
        begin
          if not iParcel.GoodsExists(AnsiString(iItem.ClassName)) then
          begin
            if ItemDB.LoadFromStr(iItem.SaveToStr,oError) and
              Reload(ItemDB,oError) then
            begin
              iParcel.PutStringGoods(AnsiString(iItem.ClassName),ItemDB.SaveToStr);
            end else begin
              oError:=Format(string('调用%s.Check错误 --> %s'),[Self.ClassName,oError]);
              Result:=False;
              Exit;
            end;
          end else if not ItemDB.LoadFromStr(iParcel.GetStringGoods(AnsiString(iItem.ClassName)),oError) then
          begin
            oError:=Format(string('调用%s.Check错误 --> %s'),[Self.ClassName,oError]);
            Result:=False;
            Exit;
          end;
          if SameStr(Trim(iItem.ModifyPsn),EmptyStr) then
          begin
            oError:='修改人不允许为空';
            Result:=False;
            Exit;
          end else if iItem.UserId<>ItemDB.UserId then
          begin
            oError:='用户账号不允许修改';
            Result:=False;
            Exit;
          end else if iItem.UserIsSystem<>ItemDB.UserIsSystem then
          begin
            oError:='用户类型不允许修改';
            Result:=False;
            Exit;
          end else if not SameStr(Trim(iItem.RecordPsn),Trim(ItemDB.RecordPsn)) then
          begin
            oError:='录入人不允许修改';
            Result:=False;
            Exit;
          end else if not SameDateTime(iItem.RecordDate,ItemDB.RecordDate) then
          begin
            oError:='录入日期不允许修改';
            Result:=False;
            Exit;
          end else if iItem.TimeStamp<>ItemDB.TimeStamp then
          begin
            oError:='用户信息已被他人修改，请重新装载...';
            Result:=False;
            Exit;
          end;
        end;
      pmDelete:
        begin
          SQL:=Format(string('SELECT COUNT(%s) FROM %s WHERE %s=''%s'' '),
                    [TSysRoleUserModel.cUserIdKey,TSysRoleUserModel.cTblName,
                    TSysRoleUserModel.cUserIdKey,iItem.UserId]);
          if TSKSOFTComm.ReadSimpleData(fServConn,fDBID,SQL,SQLResultStr,oError) then
          begin
            if StrToInt(SQLResultStr)>0 then
            begin
              oError:=Format(string('调用%s.Check错误...错误内容:当前用户已被角色引用,请先解除角色引用关系...'),[Self.ClassName]);
              Result:=False;
              Exit;
            end;
          end else begin
            oError:=Format(string('调用%s.Check错误 --> %s'),[Self.ClassName,oError]);
            Result:=False;
            Exit;
          end;

          SQL:=Format(string('SELECT COUNT(%s) FROM %s WHERE %s=''%s'' '),
                    [TSysDeptUserModel.cUserIdKey,TSysDeptUserModel.cTblName,
                    TSysDeptUserModel.cUserIdKey,iItem.UserId]);
          if TSKSOFTComm.ReadSimpleData(fServConn,fDBID,SQL,SQLResultStr,oError) then
          begin
            if StrToInt(SQLResultStr)>0 then
            begin
              oError:=Format(string('调用%s.Check错误...错误内容:当前用户已被部门引用,请先解除部门引用关系...'),[Self.ClassName]);
              Result:=False;
              Exit;
            end;
          end else begin
            oError:=Format(string('调用%s.Check错误 --> %s'),[Self.ClassName,oError]);
            Result:=False;
            Exit;
          end;

          if iItem.UserStatus<>0 then
          begin
            oError:='只允许删除已冻结的用户';
            Result:=False;
            Exit;
          end
        end;
      end;
    finally
      FreeAndNil(ItemDB);
    end;
  end else begin
    oError:=Format(string('调用%s.Check错误...错误内容:传入的对象或字符串为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysUserService.Check(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysUserService.BeforeExecute(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  if iItem<>nil then
  begin
    case iPreMode of
    pmAdd:
      begin
        iItem.TimeStamp:=TSKSOFTComm.GetTimeStampMs;
      end;
    pmEdit:
      begin
        iItem.TimeStamp:=TSKSOFTComm.GetTimeStampMs;
      end;
    pmDelete:
      begin
      end;
    pmUse:
      begin
      end;
    pmUnUse:
      begin
      end;
    end;
  end else begin
    oError:=Format(string('调用%s.BeforeExecute错误...错误内容:传入的对象或字符串为空!'),[Self.ClassName]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysUserService.BeforeExecute(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysUserService.AfterTreatment(const iItem:TSysUser; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;

function TSysUserService.AfterTreatment(const iItems:TSysUserList; const iPreMode:ePretreatmentMode; const iParcel:TQBParcel; out oError:string):Boolean;
begin
  Result:=True;
end;
{$ENDIF}

function TSysUserService.LoadAll(const iItems:TSysUserList; out oError:string; const iJustUse:Boolean):Boolean;
var
  Condition,OrderBy:string;
begin
  if (iItems<>nil) then
  begin
    if iJustUse then
    begin
      Condition:=Format(string('%s=1'),[TSysUserModel.cUserStatusKey]);
    end else begin
      Condition:='1=1';
    end;
    OrderBy:=TSysUserModel.cUserIsSystemKey+' DESC,'+TSysUserModel.cUserIdKey+' ASC';

    if not LoadByCondition(iItems,Condition,oError,OrderBy) then
    begin
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用TSysUserService.LoadAll方法失败！错误内容:传入的iItems为空!'),[]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysUserService.LoadById(const iUserId:string; const iItem:TSysUser; out oError:string):Boolean;
var
  Condition:string;
begin
  if not SameStr(Trim(iUserId),EmptyStr) and (iItem<>nil) then
  begin
    Condition:=Format(string('%s=''%s'''),[TSysUserModel.cUserIdKey,iUserId]);

    if not LoadByCondition(iItem,Condition,oError) then
    begin
      Result:=False;
      Exit;
    end;
  end else begin
    oError:=Format(string('调用TSysUserService.LoadById方法失败！错误内容:传入的iUserId或者iItem为空!'),[]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;

function TSysUserService.Login(const iOrgId,iUserId,iPassword:string; out oErrorType:Integer; out oError:string):Boolean;
var
  Condition:string;
  User:TSysUser;
  DeptUserService:TSysDeptUserService;
  DeptUserList:TSysDeptUserList;
begin
  User:=TSysUser.Create;
  DeptUserService:=TSysDeptUserService.Create(fServConn,fServConn,EmptyStr);
  DeptUserList:=TSysDeptUserList.Create;
  try
    Condition:=Format(string('%s=''%s'' and %s=%d'),[TSysUserModel.cUserIdKey,iUserId,
                                                  TSysUserModel.cUserStatusKey,1]);
    if LoadByCondition(User,Condition,oError) then
    begin
      if not SameStr(User.UserId,iUserId) then
      begin
        oErrorType:=1;
        oError:=string('用户名不存在');
        Result:=False;
        Exit;
      end else if not SameStr(User.UserPassword,iPassword) then
      begin
        oErrorType:=2;
        oError:=string('密码错误');
        Result:=False;
        Exit;
      end else if not User.UserIsSystem then
      begin
        Condition:=Format(string('%s=''%s'' and %s=''%s'' and %s=%d'),[TSysDeptUserModel.cUserIdKey,User.UserId,
                                                                      TSysDepartmentModel.cOrgIdKey,iOrgId,
                                                                      TSysDepartmentModel.cDeptStatusKey,1]);
        if DeptUserService.LoadByCondition(DeptUserList,Condition,oError,EmptyStr,eDBLoadMode.dblmView) then
        begin
          if DeptUserList.Count=0 then
          begin
            oErrorType:=3;
            oError:=string('该用户在本组织下未绑定部门');
            Result:=False;
            Exit;
          end;
        end else begin
          oErrorType:=4;
          Result:=False;
          Exit;
        end;
      end;
    end else begin
      oErrorType:=4;
      Result:=False;
      Exit;
    end;
  finally
    User.Free;
    DeptUserService.Free;
    DeptUserList.Free;
  end;
  Result:=True;
end;

function TSysUserService.Use(const iItem:TSysUser; out oError:string):Boolean;
begin
  if (iItem<>nil) then
  begin
    if iItem.UserStatus=1 then
    begin
      iItem.UserStatus:=0;
      if not inherited Edit(iItem,oError) then
      begin
        oError:=Format(string('调用%s.Use方法错误！错误内容:%s'),[Self.ClassName,oError]);
        Result:=False;
        Exit;
      end;
    end else begin
      iItem.UserStatus:=1;
      if not inherited Edit(iItem,oError) then
      begin
        oError:=Format(string('调用%s.Use方法错误！错误内容:%s'),[Self.ClassName,oError]);
        Result:=False;
        Exit;
      end;
    end;
  end else begin
    oError:=Format(string('TSysUserService.Use方法错误！错误内容:传入的iItem为空!'),[]);
    Result:=False;
    Exit;
  end;
  Result:=True;
end;
  
end.
